﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.Objects;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Text;
using System.Web;
using System.Web.Mvc;
using Find4You.Models;
using Find4You.Models.Account;
using Find4You.Util;
using System.Transactions;
using Microsoft.Web.Helpers;

namespace Find4You.Controllers
{
    public class AccountController : Controller
    {

        //
        // GET: /Account/
        private readonly f4yEntities _db = new f4yEntities();

        #region Index

        #region Index

        public ActionResult Index()
        {
            Usuario usu = new Usuario();
            if (Request.Cookies["usuario"]!=null)
            {
                string email = Request.Cookies["usuario"].Value;
                int qtde = _db.usuario.Count(u => u.Ativo && u.LoginEmail == email);
                if (qtde != 0)
                {
                    usu = _db.usuario.FirstOrDefault(u => u.Ativo && u.LoginEmail == email);
                    Session.Add("usuario", usu);
                }
            }

            return View(usu);
        }

        #endregion
        
        #region Index - HTTP - post
        [HttpPost]
        public ActionResult Index(Usuario usu)
        {
            
#if !DEBUG
            if (!ReCaptcha.Validate(ConfigurationManager.AppSettings["ReCaptcha.PrivateKey"]))
            {
                ModelState.AddModelError("", "Código de segurança (ReCaptcha) Não confere.");
            }
#endif
            if (ModelState.IsValid)
            {
                string senhaCrypt = Criptografia.Criptografar(usu.Password, Criptografia.CryptoKey);
                int qtde = _db.usuario.Count(u => u.Ativo && u.LoginEmail.Equals(usu.LoginEmail) && u.Password.Equals(senhaCrypt));
                if (qtde == 0)
                {
                    ModelState.AddModelError("LoginEmail", "E-mail ou Senha inválidos.");
                }

                if (ModelState.IsValid)
                {
                    Session.Add("usuario", _db.usuario.FirstOrDefault(u => u.Ativo && u.LoginEmail.Equals(usu.LoginEmail) && u.Password.Equals(senhaCrypt)));

                    HttpCookie cook = new HttpCookie("usuario") { Value = usu.LoginEmail, Expires=DateTime.Now.AddMonths(30) };
                    Response.AppendCookie(cook);

                    return Redirect("/Home/Index");
                }
            }
            return View(usu);
        }

        #endregion
        
        #endregion

        #region Register

        public ActionResult Register()
        {
            ViewBag.ComboUf = new SelectList(_db.uf, "IdUf", "Nome");
            return View();
        }

        [HttpPost]
        public ActionResult Register(Usuario usu)
        {
            if (string.IsNullOrWhiteSpace(usu.PasswordCompare))
            {
                ModelState.AddModelError("PasswordCompare", "Confirmação da Senha é Obrigatória.");
            }
            if (string.IsNullOrWhiteSpace(usu.Nome))
            {
                ModelState.AddModelError("Nome", "Nome é Obrigatório.");
            }

            if (usu.Password != usu.PasswordCompare)
            {
                ModelState.AddModelError("PasswordCompare", "Senha não Confere com a Cofirmação.");
            }

            if (ModelState.IsValid)
            {
                using (var tScope = new TransactionScope(TransactionScopeOption.Required))
                {
                    #region dados do usuario

                    usu.Ativo = false;
                    usu.Password = Criptografia.Criptografar(usu.Password, Criptografia.CryptoKey);
                    usu.Nivel = Usuario.NiveisUsuario.NaoDefinido.GetHashCode();
                    usu.CodigoConfirmacao = Guid.NewGuid().ToString().ToUpper().Replace("-", string.Empty);

                    #endregion

                    _db.usuario.AddObject(usu);
                    _db.SaveChanges();
                    string currentControllerName = (string)RouteData.Values["controller"];
                    //string currentActionName = (string) RouteData.Values["action"];


                    #region Enviar Email

                    string remetenteEmail = ConfigurationManager.AppSettings["RemetenteEmail"]; //O e-mail do remetente
                    string passwordEmail = ConfigurationManager.AppSettings["PasswordEmail"];
                    SmtpClient client = new SmtpClient();
                    client.Credentials = new NetworkCredential(remetenteEmail, passwordEmail);
                    client.EnableSsl = false;  //Adicionando as credenciais do seu e-mail e senha:

                    var mail = new MailMessage
                                   {
                                       From = new MailAddress(remetenteEmail, "Find 4 You", Encoding.UTF8),
                                       Subject = string.Format("Confirmação de Registro de {0}", usu.Nome),
                                       SubjectEncoding = Encoding.UTF8,
                                       Body = string.Format(@"
Sr(a). {0}, <br /><br />
Obrigado por se Registrar no <a href='www.find4you'>Find 4 You</a><br /><br />
para confirmar seu cadastro, acesse a opção confirmar cadastro e forneça o codigo: {1}<br /><br />
ou utilize a url abaixo: http://www.find4you.com.br/{2}/ConfirmarCadastro?qString={1} <br /><br />

Cordialmente,<br /><br />
Find 4 You
", usu.Nome, usu.CodigoConfirmacao, currentControllerName),
                                       BodyEncoding = Encoding.UTF8,
                                       IsBodyHtml = true,
                                       Priority = MailPriority.Normal
                                   };

                    mail.To.Add(usu.LoginEmail);
                    //mail.Bcc.Add(remetenteEmail);

                    try
                    {
                        client.Send(mail);
                    }
                    catch
                    {
                        //  so reporta erro se nao for debug para funcionar no ambiente de desenvolvimento
#if !DEBUG
                    throw;
#endif
                        Console.WriteLine(mail.Body);
                    }

                    #endregion

                    tScope.Complete();
                    
                }

                HttpCookie cook = new HttpCookie("usuario") { Value = usu.LoginEmail, Expires = DateTime.Now.AddMonths(30) };
                Request.Cookies.Add(cook);
                return RedirectToAction("Index");
            }
            usu.Password = string.Empty;
            usu.PasswordCompare = string.Empty;
            ViewBag.ComboUf = new SelectList(_db.uf, "IdUf", "Nome", usu.IdUf);

            return View();
        }
        #endregion

        #region Confirmar Cadastro

        public ActionResult ConfirmarCadastro(string qString)
        {
            if (!string.IsNullOrWhiteSpace(qString))
            {
                Confirmar(qString);
                ViewBag.MensagemConfirmacao = "Cadastro confirmado com sucesso.";
                return RedirectToAction("ConfirmacaoSuccess");
            }

            return View();
        }

        [HttpPost]
        public ActionResult ConfirmarCadastro(Usuario usu)
        {
            string codConf = usu.CodigoConfirmacao;
            if (string.IsNullOrWhiteSpace(codConf))
            {
                ModelState.AddModelError("CodigoConfirmacao", "Codigo de confirmação é obrigatório.");
            }
            else
            {
                Confirmar(codConf);
                ViewBag.MensagemConfirmacao = "Cadastro confirmado com sucesso.";
                return RedirectToAction("ConfirmacaoSuccess");
                
            }
            return View(usu);
        }

        public ActionResult ConfirmacaoSuccess()
        {
            return View();
        }

        #endregion

        #region Esqueceu a Senha
        public ActionResult EsqueceuSenha()
        {
            if (Session["usuario"] != null)
            {
                Usuario usu = Session["usuario"] as Usuario;
                return View(usu);
            }
            return View();
        }

        [HttpPost]
        public ActionResult EsqueceuSenha(Usuario usu)
        {
            //bool modeloValido = TryUpdateModel<Usuario>(usu, new string[] { "LoginEmail" });
            ;
            if (!string.IsNullOrWhiteSpace(usu.LoginEmail))
            {
                int qtde = _db.usuario.Count( u => u.Ativo && u.LoginEmail.Equals(usu.LoginEmail) );
                if (qtde == 0 )
                {
                    ModelState.AddModelError("LoginEmail", string.Format("E-mail não cadastrado."));
                }
                else
                {
                    string senhaReset = Guid.NewGuid().ToString().ToUpper().Replace("-", string.Empty).Substring(0, 12);
                    using (var tScope = new TransactionScope(TransactionScopeOption.Required))
                    {
                        var usuPass = _db.usuario.FirstOrDefault(u => u.Ativo && u.LoginEmail.Equals(usu.LoginEmail));
                        usuPass.Password = Criptografia.Criptografar(senhaReset, Criptografia.CryptoKey);
                        _db.ObjectStateManager.ChangeObjectState(usuPass, EntityState.Modified);
                        _db.SaveChanges(SaveOptions.DetectChangesBeforeSave);
                        tScope.Complete();

                        #region Envio de email
                        string remetenteEmail = ConfigurationManager.AppSettings["RemetenteEmail"]; //O e-mail do remetente
                        string passwordEmail = ConfigurationManager.AppSettings["PasswordEmail"];
                        SmtpClient client = new SmtpClient();
                        client.Credentials = new NetworkCredential(remetenteEmail, passwordEmail);
                        client.EnableSsl = false;  //Adicionando as credenciais do seu e-mail e senha:

                        MailMessage mail = new MailMessage
                                               {
                                                   From = new MailAddress(remetenteEmail, "Find 4 You", Encoding.UTF8),
                                                   Subject = string.Format("Nova senha do Find 4 You gerada para {0}", usuPass.Nome),
                                                   SubjectEncoding = Encoding.UTF8,
                                                   Body = string.Format(@"
Sr(a). {0}, <br /><br />
Foi solicitado uma nova senha no site <a href='www.find4you.com.br'>Find 4 You</a>.<br /><br />
Sua nova senha é: {1}<br /><br />
você poderá trocar a senha no próprio site em: http://find4you/Account/TrocarSenha <br /><br />

Cordialmente,<br /><br />
Find for You
", usuPass.Nome, senhaReset),
                                                   BodyEncoding = Encoding.UTF8,
                                                   IsBodyHtml = true,
                                                   Priority = MailPriority.Normal
                                               };

                        mail.To.Add(usuPass.LoginEmail);
                        //mail.Bcc.Add(remetenteEmail);

                        try
                        {
                            client.Send(mail);
                        }
                        catch
                        {
                            //  so reporta erro se nao for debug para funcionar no ambiente de desenvolvimento
#if !DEBUG
                    throw;
#endif
                            Console.WriteLine(mail.Body);
                        }
                        #endregion

                        ViewBag.MensagemConfirmacao = "Senha Gerada com sucesso, por favor verifique seu e-mail.";
                    }
                }
            }
            else
            {
                ModelState.AddModelError("LoginEmail", string.Format("E-mail é Obrigatório."));
                
            }
            return View(usu);
        }
        #endregion

        #region TrocaSenha

        public ActionResult TrocaSenha()
        {
            if (Session["usuario"] == null) return RedirectToAction("Index");
            Usuario usu = (Usuario) Session["usuario"];
            ViewBag.LoginEmail = usu.LoginEmail;

            return View();
        }

        [HttpPost]
        public ActionResult TrocaSenha(TrocaSenha model)
        {
            if (Session["usuario"]==null ) return RedirectToAction("Index");
            Usuario usuLog = (Usuario) Session["usuario"];
            ViewBag.LoginEmail = usuLog.LoginEmail;
            string senhaCrypt = Criptografia.Criptografar(model.OldPassword, Criptografia.CryptoKey);
            if (_db.usuario.FirstOrDefault(u => u.Ativo && u.LoginEmail == usuLog.LoginEmail).Password != senhaCrypt)
            {
                ModelState.AddModelError("OldPassword", "Senha Atual não confere.");
            }
            else if (model.OldPassword==model.NewPassword)
            {
                ModelState.AddModelError("NewPassword", "Nova Senha é a atual.");
            }
            else if (model.NewPassword!=model.ReNewPassword)
            {
                ModelState.AddModelError("NewPassword", "Senha não Confere com a Cofirmação.");
            }

            if (ModelState.IsValid)
            {
                using (var tScope = new TransactionScope(TransactionScopeOption.Required))
                {
                    Usuario usu = _db.usuario.FirstOrDefault(u => u.Ativo && u.LoginEmail == usuLog.LoginEmail);
                    senhaCrypt = Criptografia.Criptografar(model.NewPassword, Criptografia.CryptoKey);
                    usu.Password = senhaCrypt;

                    _db.ObjectStateManager.ChangeObjectState(usu, EntityState.Modified);
                    _db.SaveChanges(SaveOptions.DetectChangesBeforeSave);
                    
                    tScope.Complete();
                    ViewBag.MensagemConfirmacao = "Senha alterdo com sucesso.";
                    
                }
            }

            return View();

        }

        #endregion


        #region Metodos

        #region Confirmar

        private void Confirmar(string codigoConfirmacao)
        {
            int cont = _db.usuario.Where(u => !u.Ativo && u.CodigoConfirmacao == codigoConfirmacao).Count();
            if (cont == 0)
            {
                ModelState.AddModelError("", "Codigo de Confirmação não encontrado.");
                return;
            }
            using (var tScope = new TransactionScope(TransactionScopeOption.Required))
            {
                Usuario usu = _db.usuario.FirstOrDefault(u => !u.Ativo && u.CodigoConfirmacao == codigoConfirmacao);
                usu.Ativo = true;
                usu.CodigoConfirmacao = string.Empty;
                //Servicos.Db.usuario.Attach(usu);
                //Servicos.Db.AcceptAllChanges();
                _db.ObjectStateManager.ChangeObjectState(usu, System.Data.EntityState.Modified);
                _db.SaveChanges(System.Data.Objects.SaveOptions.DetectChangesBeforeSave);
                
                tScope.Complete();
                
            }
        }

        #endregion

        #endregion

    }
}
